package com.xingfei.blog.service.impl;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.xingfei.blog.annoations.MyCacheEvict;
import com.xingfei.blog.baseMapper.ArticleContentMapper;
import com.xingfei.blog.baseMapper.ArticleMapper;
import com.xingfei.blog.constants.ErrorConstants;
import com.xingfei.blog.dto.ArticleContentDTO;
import com.xingfei.blog.dto.ArticleDTO;
import com.xingfei.blog.dto.CollectionDTO;
import com.xingfei.blog.mapper.ArticleDOMapper;
import com.xingfei.blog.model.ArticleContentDO;
import com.xingfei.blog.model.ArticleDO;
import com.xingfei.blog.model.CollectionDO;
import com.xingfei.blog.redisCluster.dao.RedisClusterDao;
import com.xingfei.blog.result.ResultConstructor;
import com.xingfei.blog.result.ServiceResult;
import com.xingfei.blog.service.BlogArticleService;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2017/2/18.
 */
@Service("blogArticleService")
public class BlogArticleServiceImpl implements BlogArticleService {


    @Autowired
    private ArticleDOMapper articleDOMapper;
    //通用mapper
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private ArticleContentMapper articleContentMapper;
    @Autowired
    private RedisClusterDao redisClusterDao;

    // 日志
    private static Logger logger = LoggerFactory.getLogger(BlogArticleServiceImpl.class);

    /**
     * 添加新文章
     * @param articleDTO
     * @return
     */
    @Override
    @Transactional
//    @CachePut(value = "articles",key = "'article_'.concat(#articleDTO.getId())")
//    @MyCacheEvict(value = "articles", keyRegex = "list")
    public ServiceResult<ArticleDTO> saveArticle(ArticleDTO articleDTO){
        if (articleDTO == null) {
            return ResultConstructor.buildServiceErrResult(ErrorConstants.RES_SERVICE_STRING, "条件错误");
        }
        ArticleDO articleDO = new ArticleDO();
        BeanUtils.copyProperties(articleDTO, articleDO);
        int i = this.articleMapper.insertSelective(articleDO);
        if(i>0){
            //保存文章内容
            if(articleDO.getId()!=null){
                articleDTO.setId(articleDO.getId());
                ArticleContentDTO articleContentDTO = articleDTO.getArticleContentDTO();
                articleContentDTO.setArticleId(articleDTO.getId());
                ArticleContentDO articleContentDO = new ArticleContentDO();
                BeanUtils.copyProperties(articleContentDTO,articleContentDO);
                int i1 = articleContentMapper.insertSelective(articleContentDO);
                if(i1>0){
                    return ResultConstructor.buildSuccessResult(articleDTO, ErrorConstants.RES_SUCCESS, "操作成功");
                }
            }
        }
        return ResultConstructor.buildSuccessResult(null, ErrorConstants.RES_SUCCESS, "操作失败");
    }

    /**
     * 根据文章id获取文章信息
     *
     * @param articleId
     * @return
     */
    @Override
//    @Cacheable(value = "articles",key = "'article_'.concat(#articleId)")
    public ServiceResult<ArticleDTO> getArticleById(Long articleId) {
        try {
            if (articleId == null) {
                return ResultConstructor.buildServiceErrResult(ErrorConstants.RES_SERVICE_STRING, "条件错误");
            }
            ArticleDO article = this.articleMapper.getArticleById(articleId);
            if (article != null) {
                ArticleDTO articleDTO = new ArticleDTO();
                BeanUtils.copyProperties(article, articleDTO);
                if(article.getArticleContentDO()!=null){
                    ArticleContentDTO articleContentDTO = new ArticleContentDTO();
                    BeanUtils.copyProperties(article.getArticleContentDO(), articleContentDTO);
                    articleDTO.setArticleContentDTO(articleContentDTO);
                }
                return ResultConstructor.buildSuccessResult(articleDTO, ErrorConstants.RES_SUCCESS, "操作成功");
            } else {
                return ResultConstructor.buildSuccessResult(null, ErrorConstants.RES_SUCCESS, "没有查询导数据");
            }
        } catch (Exception e) {
//            记录日志
            logger.error("findArticleById error, case: " + e.getMessage());
//            返回错误信息
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }

    @Override
    public ServiceResult<Long> getPublisherIdByArticleId(Long articleId) {
        Long publisherId = this.articleMapper.getPublisherIdByArticleId(articleId);
        return ResultConstructor.buildSuccessResult(publisherId, ErrorConstants.RES_SUCCESS, "操作成功");
    }

    @Override
    public ServiceResult<List<ArticleDTO>> listByPage(ArticleDTO articleDTO, Integer pageNum, Integer pageSize) {
        //转换数据
        List<ArticleDTO> articleDTOList = null;
        try {
            ArticleDO articleDO = new ArticleDO();
            BeanUtils.copyProperties(articleDTO, articleDO);
            //内存分页
//            List<ArticleDO> articleDOS = this.articleMapper.selectByRowBounds(articleDO, new RowBounds(pageNum, pageSize));
            Example example = new Example(ArticleDO.class);
            getArticleSelectCondition(example, articleDTO);
            List<ArticleDO> articleDOS = articleMapper.selectByExampleAndRowBounds(example, new RowBounds(pageNum, pageSize));
            //物理分页
//           PageHelper.startPage(1, 2);
//           List<ArticleDO> articleDOS = articleMapper.selectAll();
//           Page<ArticleDO> page = (Page<ArticleDO>) articleDOS;
            articleDTOList = new ArrayList<>();
            copyArticleData(articleDOS, articleDTOList);
            return ResultConstructor.buildSuccessResult(articleDTOList, ErrorConstants.RES_SUCCESS, "查询成功");
        } catch (BeansException e) {
            e.printStackTrace();
            // 记录日志
            logger.error("findArticleById error, case: " + e.getMessage());
            // 返回错误信息
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }

    /**
     * 查询文章列表
     *
     * @param articleDTO
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    //@Cacheable(value = "articles",key = "'listByPageNew'.concat(#pageNum)")
    public ServiceResult<List<ArticleDTO>> listByPageNew(ArticleDTO articleDTO, Integer pageNum, Integer pageSize) {
        if (articleDTO == null) {
            return ResultConstructor.buildServiceErrResult(ErrorConstants.RES_SERVICE_STRING, "条件错误");
        }
        try {
            ArticleDO articleDO = new ArticleDO();
            BeanUtils.copyProperties(articleDTO,articleDO);
            pageNum = (pageNum - 1) * pageSize;
//            List<ArticleDO> articleDOS = this.articleMapper.listArticles(articleDO, pageNum, pageSize);
            List<ArticleDO> articleDOS = this.articleMapper.listArticlesoForIndex(articleDO, pageNum, pageSize);
            List<ArticleDTO> articleDTOList = new ArrayList<>();
            if(CollectionUtils.isNotEmpty(articleDOS)){
                //复制数据
                copyArticleData(articleDOS, articleDTOList);
            }
            return ResultConstructor.buildSuccessResult(articleDTOList, ErrorConstants.RES_SUCCESS, "查询成功");
        } catch (BeansException e) {
            e.printStackTrace();
            // 记录日志
            logger.error("findArticleById error, case: " + e.getMessage());
            // 返回错误信息
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }

    @Override
    public ServiceResult<List<ArticleDTO>> listColletionArticleFormeByPage(CollectionDTO collectionDTO, Integer pageNum, Integer pageSize) {
        if (collectionDTO == null) {
            return ResultConstructor.buildServiceErrResult(ErrorConstants.RES_SERVICE_STRING, "条件错误");
        }
        try {
            CollectionDO collectionDO = new CollectionDO();
            BeanUtils.copyProperties(collectionDTO,collectionDO);
            List<ArticleDO> articleDOS  = articleMapper.listColletionArticleFormeByPage(collectionDO, pageNum, pageSize);
            List<ArticleDTO> articleDTOList = new ArrayList<>();
            if(CollectionUtils.isNotEmpty(articleDOS)){
                //复制数据
                copyArticleData(articleDOS, articleDTOList);
            }
            return ResultConstructor.buildSuccessResult(articleDTOList, ErrorConstants.RES_SUCCESS, "查询成功");
        } catch (BeansException e) {
            e.printStackTrace();
            // 记录日志
            logger.error("findArticleById error, case: " + e.getMessage());
            // 返回错误信息
            return ResultConstructor.buildRunTimeErrResult(e.getMessage());
        }
    }

    /**
     * do和dto数据转换
     * @param articleDOS
     * @param articleDTOList
     */
    private void copyArticleData(List<ArticleDO> articleDOS, List<ArticleDTO> articleDTOList) {
        if (CollectionUtils.isNotEmpty(articleDOS)) {
            //转换数据，并返结果
            for (ArticleDO DO : articleDOS) {
                ArticleDTO dto = new ArticleDTO();
                BeanUtils.copyProperties(DO, dto);
                if(DO.getArticleContentDO()!=null){
                    ArticleContentDTO contentDTO = new ArticleContentDTO();
                    BeanUtils.copyProperties(DO.getArticleContentDO(),contentDTO);
                    dto.setArticleContentDTO(contentDTO);
                }
                articleDTOList.add(dto);
            }
        }
    }

    /**
     * 组装文章列表查询条件
     *
     * @param example
     * @param articleDTO
     */
    private void getArticleSelectCondition(Example example, ArticleDTO articleDTO) {
        //排序
//        example.setOrderByClause("createTime desc");
        //封装发布文章的作者id
        Example.Criteria criteria = example.createCriteria();
        //文章类型
        if (articleDTO.getArticleType() != null) {
            criteria.andEqualTo("articleType", articleDTO.getArticleType());
        }
        //用户id
        if (articleDTO.getUserId() != null) {
            criteria.andEqualTo("userId", articleDTO.getUserId());
        }
        //是否置顶
        criteria.andEqualTo("isTop", articleDTO.getIsTop());
        //是否置顶
        criteria.andEqualTo("isSupported", articleDTO.getIsSupported());
    }
}
